<template>
	<vi-dialog ref="dialog"
		:point="setting.point"
		:maskClick="setting.maskClick"
		:radius="setting.radius"
		:title="inTitle"
		:useTitle="!!inTitle"
		:useContent="setting.useContent"
		:topbar="setting.topbar"
		:bottombar="setting.bottombar"
		:toolbar="setting.toolbar"
		:width="setting.width"
		:maxWidth="setting.maxWidth"
		:maxHeight="setting.maxHeight"
		:bodyHeight="setting.bodyHeight"
		:spaceOutside="setting.spaceOutside"
		:shift="inShift"
		@event="onEvent"
		@opened="winOpend"
		@change="winChange">
		<view :style="setting.style">
			<slot>
				<text>{{inContent}}</text>
			</slot>
		</view>
	</vi-dialog>
</template>

<script>
	// 本组件是vi-dialog的方案定制版本，用于立即成型，快速调用，省去重复配置参数
	// 方案定义位于options.js
	import options from "./options.js"
	export default{
		name:"commonDialog",
		props:{
			title:{
				type:[String,null],
				default:""
			},
			content:{
				type:[String,null],
				default:""
			},
			params:{
				//无格式限制，但建议是对象
				default:null
			},
			//使用方案名
			mode:{
				type:[String,null],
				default:""
			},
			//text文字键名为按钮的 event名
			text:{
				type:[Object,null],
				default:()=>({})
			},
			//特殊设置覆盖
			options:{
				type:[Object,null],
				default:()=>({})
			},
			//窗口偏移
			shift:{
				type:[Object,null],
				default:()=>({})
			}
		},
		data(){
			return {
				inTitle:"",
				inContent:"",
				inParams:null,
				inOptions:{},
				inShift:{},
			}
		},
		computed:{
			//options的topbar、bottombar、toolbar属性将会覆盖对应bar的所有数据
			//options的topOptions、bottomOptions、toolOptions属性将会覆盖对应bar下的属性
			//options的topList、bottomList、toolList属性将会覆盖对应bar下的list数据
			setting(){
				let text = this.$api.isObject(this.text)? this.text :{},
					name = this.mode || Object.keys(options)[0],
					res = this.$api.clone(options[name]);//深层结构数据必须克隆，否则内部对象引用会造成复用组件间参数冲突
				let bars = ["topbar", "bottombar", "toolbar"],
					subOptions = ["topOptions","bottomOptions","toolOptions"],
					subLists = ["topList","bottomList","toolList"];
				this.merge(res, this.options, this.inOptions);
				//覆盖子选项集
				for(let subOption of subOptions){
					if(res[subOption]){
						let key = subOption.split("Options")[0] + "bar";
						Object.assign(res[key], res[subOption])
					}
				}
				//覆盖子列表
				for(let subList of subLists){
					if(res[subList]){
						let key = subList.split("List")[0] + "bar";
						res[key]["list"] = res[subList]
					}
				}
				//覆盖按钮文字
				for(let bar of bars){
					let list = this.$api.objPathGet(res, bar+".list") ||[];
					for(let btn of list){
						if(text[btn.event]){
							btn.name = text[btn.event]
						}
					}
				}
				return res
			}
		},
		methods:{
			open(dataSet){
				if(dataSet){
					let {title, content, params, options} = dataSet;
					title? this.inTitle = title :"";
					content? this.inContent = content :"";
					this.$api.isValue(params)? this.inParams = params :"";
					this.$api.isObject(options)? this.inOptions = options :"";
				}
				this.$refs.dialog.open();
			},
			close(){
				this.$refs.dialog.close();
			},
			onEvent(e){
				//提交两种格式的事件
				this.$emit(e.event, this.inParams);
				this.$emit("event", {
					event: e.event,
					params: this.inParams,
					button: e,
				});
			},
			winOpend(){
				this.$emit("opened")
			},
			winChange(e){
				this.$emit("change", e)
			},
			//对象合并，深层数据不能直接覆盖
			//注意这里不检查循环引用
			merge(...objs){
				let res = objs[0] ||{};
				for(let i=1,len=objs.length; i<len; i++){
					let obj = objs[i],
						keys = Object.keys(obj);
					for(let key of keys){
						let val = obj[key];
						if(val==undefined||val==null){
							continue
						}
						if(this.$api.isObject(val)){
							this.merge(res[key], val)
						}else if(this.$api.isArray(val)){
							res[key] = this.$api.clone(val)
						}else{
							res[key] = val
						}
					}
				}
				return res
			}
		},
		watch:{
			"title":{
				immediate:true,
				handler(newValue){
					this.inTitle = newValue||""
				}
			},
			"content":{
				immediate:true,
				handler(newValue){
					this.inContent = newValue||""
				}
			},
			"params":{
				immediate:true,
				handler(newValue){
					this.inParams = newValue
				}
			},
			"shift":{
				immediate:true,
				handler(newValue){
					this.inShift = newValue ||{}
				}
			}
		}
	}
</script>

<style lang="scss">

</style>